package com.itheima.domain;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SpringApplicationContext {
    private Map<String, Object> map = new HashMap<>();
    private String xmlName;

    public SpringApplicationContext(String xmlName) {
        this.xmlName = xmlName;
        parseXml();
    }

    private void parseXml() {
        //创建解析器对象
        SAXReader saxReader = new SAXReader();
        try {
            //使用解析器对象读取XML文档生成Document对象
            InputStream in = this.getClass().getClassLoader().getResourceAsStream(xmlName);
            Document xmlDom = saxReader.read(in);
            //获取文档的根节点<beans>下的所有<bean>节点
            Element rootElement = xmlDom.getRootElement();
            List<Element> beanList = rootElement.elements();
            //判断根节点<beans>下有没有<bean>节点
            if (beanList != null && beanList.size() > 0) {
                //有
                for (Element bean : beanList) {
                    //获取bean标签的id和class属性
                    String id = bean.attributeValue("id");
                    String className = bean.attributeValue("class");
                    //通过反射加载类对象
                    Class<?> clazz = Class.forName(className);
                    Object obj = clazz.newInstance();
                    //获取bean标签下的所有property标签
                    List<Element> propertyList = bean.elements();
                    if (propertyList != null && propertyList.size() > 0) {
                        for (Element property : propertyList) {
                            //获取<property>标签的name属性
                            String name = property.attributeValue("name");
                            //根据name获取类中的属性值
                            Field declaredField = clazz.getDeclaredField(name);
                            declaredField.setAccessible(true);
                            //获取<property>标签的value属性
                            String value = property.attributeValue("value");
                            if (value != null && !value.equals("")) {
                                //为属性设置值
                                declaredField.set(obj, value);
                            }
                        }
                    }
                    //将获取的bean对象存入到Map集合中
                    map.put(id, obj);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //根据beanId从Map集合中获取bean对象
    public <T> T getBean(String beanId) {
        return (T) map.get(beanId);
    }
}
